package com.pzr.soccer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.pzr.soccer.feign.OAuth2FeignClient;
import com.pzr.soccer.model.JwtToken;
import com.pzr.soccer.model.LoginResult;
import com.pzr.soccer.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author pzr
 * @date:2021-12-21-15:34
 * @Description:
 **/
@Slf4j
@Service
public class LoginServiceImpl implements LoginService {
    @Value("${basic.token:Basic Y2xpZW50OjEyMzQ1Ng==}")
    private String basicToke;
    @Autowired
    OAuth2FeignClient oAuth2FeignClient;
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Override
    public LoginResult login(String username, String password) {
        ResponseEntity<JwtToken> jwtTokenResp=null;
        //处理用户密码错
        try {
             jwtTokenResp = oAuth2FeignClient.getToken("password", username, password, "password", basicToke);
        }catch (Exception fe){
                    if(fe.getMessage().contains("用户名或密码错误")){
                        throw new UsernameNotFoundException("用户名或密码错误");
                    }
        }
        //处理其他错误
        if (jwtTokenResp==null||jwtTokenResp.getStatusCode() != HttpStatus.OK) {
            log.error(username+" get token failed");
            throw new ApiException(ApiErrorCode.FAILED);
        }
         JwtToken jwtToken=jwtTokenResp.getBody();
        assert jwtToken != null;
        String token=jwtToken.getAccessToken();
        log.info("成功获取token");

        //解析token,转换成json object
        String tokenStr= JwtHelper.decode(token).getClaims();
        JSONObject tokenJsonObj= JSON.parseObject(tokenStr);

        //取数
        //String userId=tokenJsonObj.getString("id");
        JSONArray jsonArray=tokenJsonObj.getJSONArray("authorities");
        List<String> authorities = jsonArray.stream().map(Object::toString).collect(Collectors.toList());

        // 1 将该token 存储在redis 里面，配置我们的网关做jwt验证的操作
        redisTemplate.opsForValue().set(token,"",jwtToken.getExpiresIn(), TimeUnit.SECONDS);
        log.info("current principal: ");
        log.info(JSON.toJSONString(SecurityContextHolder.getContext().getAuthentication().getPrincipal(),true));
        return new LoginResult(jwtToken.getTokenType()+" "+token,authorities) ;
    }
}
